#ifndef __CPIL_ITERATOR_HPP__
#define __CPIL_ITERATOR_HPP__

#include <exception.hpp>
#include <memory.hpp>
#include <sharedarray.hpp>

template< typename DataType >
class ConstIterator
{
    protected:

        DataType * ptr;

        inline ConstIterator(DataType * data) : ptr(data) {}

    public:

        inline ConstIterator() : ptr(0) {}
        inline ~ConstIterator() {}
        inline ConstIterator(const ConstIterator &iterator) : ptr(iterator.ptr) {}
        inline ConstIterator& operator=(const ConstIterator &iterator)
        {
            ptr = iterator.ptr;
            return (*this);
        }

        inline ConstIterator(const SharedArray<DataType> &sp) : ptr(sp.data) {}
        inline ConstIterator& operator=(const SharedArray<DataType> &sp)
        {
            ptr = sp.data;
            return (*this);
        }

        //pre-inc
        inline ConstIterator& operator++()    { ++ptr;return(*this); }
        inline ConstIterator& operator--()    { --ptr;return(*this); }
        inline ConstIterator  operator++(int) {ConstIterator res(*this);ptr++;return res;}
        inline ConstIterator  operator--(int) {ConstIterator res(*this);ptr--;return res;}

        inline ConstIterator& operator+=(unsigned int shift) { ptr+=shift;return (*this); }
        inline ConstIterator& operator-=(unsigned int shift) { ptr-=shift;return (*this); }

        inline ConstIterator  operator+(unsigned int shift) { return ConstIterator(ptr+shift);}
        inline ConstIterator  operator-(unsigned int shift) { return ConstIterator(ptr-shift);}

        inline DataType operator*() const { return *ptr; }


};

template < typename DataType >
class Iterator// : public ConstIterator<T>
{
    protected:

        DataType * ptr;
        Iterator(DataType * data) : ptr(data) {}

    public:

        inline Iterator() : ptr(0) {}
        inline ~Iterator() {}
        inline Iterator(const Iterator &iterator) : ptr(iterator.ptr) {}
        inline Iterator& operator=(const Iterator &iterator)
        {
            ptr = iterator.ptr;
            return (*this);
        }

        inline Iterator(SharedArray<DataType> &sp) : ptr(sp.data)
        {
            sp.unsharObject();
        }

        inline Iterator& operator=(SharedArray<DataType> &sp)
        {
            sp.unsharObject();
            ptr = sp.data;
            return (*this);
        }

        inline Iterator& operator++()    { ++ptr;return(*this); }
        inline Iterator& operator--()    { --ptr;return(*this); }
        inline Iterator  operator++(int) {Iterator res(*this);ptr++;return res;}
        inline Iterator  operator--(int) {Iterator res(*this);ptr--;return res;}

        inline Iterator& operator+=(unsigned int shift) { ptr+=shift;return (*this); }
        inline Iterator& operator-=(unsigned int shift) { ptr-=shift;return (*this); }
        inline Iterator  operator+(unsigned int shift) { return Iterator(ptr+shift);}
        inline Iterator  operator-(unsigned int shift) { return Iterator(ptr-shift);}

        inline DataType& operator*() { return *ptr; }

};


#endif
